Completed
Push — master ( 6b6ac0...3b283c )
by Sander
02:25
created

angular.controller(ꞌCredentialCtrlꞌ)   C

Complexity

Conditions 8
Paths 32

Size

Total Lines 397

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 8
nc 32
nop 19
dl 0
loc 397
rs 5.2676
c 2
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
(function () {
24
	'use strict';
25
26
27
	/**
28
	 * @ngdoc function
29
	 * @name passmanApp.controller:MainCtrl
30
	 * @description
31
	 * # MainCtrl
32
	 * Controller of the passmanApp
33
	 */
34
	angular.module('passmanApp')
35
		.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
36
			'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService', 'ShareService', 'SharingACL', '$interval', '$filter', '$routeParams', '$sce', '$translate',
37
			function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService, ShareService, SharingACL, $interval, $filter, $routeParams, $sce, $translate) {
38
				$scope.active_vault = VaultService.getActiveVault();
39
				if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
40
					if (!$scope.active_vault) {
41
						$location.path('/');
42
					}
43
				} else {
44
					if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
45
						var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
46
						_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
47
						VaultService.setActiveVault(_vault);
48
						$scope.active_vault = _vault;
49
						//@TODO check if vault exists
50
					}
51
				}
52
53
				$scope.show_spinner = true;
54
				var fetchCredentials = function () {
55
					VaultService.getVault({guid: $routeParams.vault_id}).then(function (vault) {
56
						var vaultKey = angular.copy($scope.active_vault.vaultKey);
57
						var _credentials = angular.copy(vault.credentials);
58
						vault.credentials = [];
59
						$scope.active_vault = vault;
60
						$scope.active_vault.vaultKey = vaultKey;
61
						VaultService.setActiveVault($scope.active_vault);
62
						for (var i = 0; i < _credentials.length; i++) {
63
							var _credential = _credentials[i];
64
							try {
65
								if (!_credential.shared_key) {
66
									_credential = CredentialService.decryptCredential(angular.copy(_credential));
67
68
								} else {
69
									var enc_key = EncryptService.decryptString(_credential.shared_key);
70
									_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
71
								}
72
								_credential.tags_raw = _credential.tags;
73
							} catch (e) {
74
75
								NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
76
								//$rootScope.$broadcast('logout');
77
								//SettingsService.setSetting('defaultVaultPass', null);
78
								//.setSetting('defaultVault', null);
79
								//$location.path('/')
80
81
							}
82
							if (_credential.tags) {
83
								TagService.addTags(_credential.tags);
84
							}
85
							_credentials[i] = _credential;
86
						}
87
88
						ShareService.getCredendialsSharedWithUs(vault.guid).then(function (shared_credentials) {
89
							for (var c = 0; c < shared_credentials.length; c++) {
90
								var _shared_credential = shared_credentials[c];
91
								var decrypted_key = EncryptService.decryptString(_shared_credential.shared_key);
92
								var _shared_credential_data;
93
								try {
94
									_shared_credential_data = ShareService.decryptSharedCredential(_shared_credential.credential_data, decrypted_key);
95
								} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
96
97
								}
98
								if (_shared_credential_data) {
99
									delete _shared_credential.credential_data;
100
									_shared_credential_data.acl = _shared_credential;
101
									_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
102
									_shared_credential_data.tags_raw = _shared_credential_data.tags;
103
									if (_shared_credential_data.tags) {
104
										TagService.addTags(_shared_credential_data.tags);
105
									}
106
									_credentials.push(_shared_credential_data);
107
								}
108
							}
109
							angular.merge($scope.active_vault.credentials, _credentials);
110
							$scope.show_spinner = false;
111
						});
112
					});
113
				};
114
115
				var getPendingShareRequests = function () {
116
					ShareService.getPendingRequests().then(function (shareRequests) {
117
						if (shareRequests.length > 0) {
118
							$scope.incoming_share_requests = shareRequests;
119
							jQuery('.share_popup').dialog({
120
								width: 600,
121
								position: ['center', 90]
122
							});
123
						}
124
					});
125
				};
126
127
128
				var refresh_data_interval = null;
129
				if ($scope.active_vault) {
130
					$scope.$parent.selectedVault = true;
131
					fetchCredentials();
132
					getPendingShareRequests();
133
					refresh_data_interval = $interval(function () {
134
						fetchCredentials();
135
						getPendingShareRequests();
136
					}, 60000 * 5);
137
				}
138
				$scope.$on('$destroy', function () {
139
					$interval.cancel(refresh_data_interval);
140
				});
141
142
143
				$scope.permissions = new SharingACL(0);
144
145
				$scope.hasPermission = function (acl, permission) {
146
					if (acl) {
147
						var tmp = new SharingACL(acl.permission);
148
						return tmp.hasPermission(permission);
149
					} else {
150
						return true;
151
					}
152
153
				};
154
155
				$scope.acceptShareRequest = function (share_request) {
156
					var crypted_shared_key = share_request.shared_key;
157
					var private_key = EncryptService.decryptString(VaultService.getActiveVault().private_sharing_key);
158
159
					private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
160
					/** global: forge */
161
					crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
162
					crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
163
164
					ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function () {
165
						var idx = $scope.incoming_share_requests.indexOf(share_request);
166
						$scope.incoming_share_requests.splice(idx, 1);
167
						var active_share_requests = false;
168
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
169
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
170
								active_share_requests = true;
171
							}
172
						}
173
						if (active_share_requests === false) {
174
							jQuery('.ui-dialog').remove();
175
							fetchCredentials();
176
						}
177
					});
178
				};
179
180
				$scope.declineShareRequest = function (share_request) {
181
					ShareService.declineSharingRequest(share_request).then(function () {
182
						var idx = $scope.incoming_share_requests.indexOf(share_request);
183
						$scope.incoming_share_requests.splice(idx, 1);
184
						var active_share_requests = false;
185
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
186
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
187
								active_share_requests = true;
188
							}
189
						}
190
						if (active_share_requests === false) {
191
							jQuery('.ui-dialog').remove();
192
							fetchCredentials();
193
						}
194
					});
195
				};
196
197
198
				var settingsLoaded = function () {
199
					$scope.settings = SettingsService.getSettings();
200
				};
201
202
				if(!SettingsService.getSetting('settings_loaded')){
203
					$rootScope.$on('settings_loaded', function () {
204
						settingsLoaded();
205
					});
206
				} else {
207
					settingsLoaded();
208
				}
209
210
211
				$scope.addCredential = function () {
212
					var new_credential = CredentialService.newCredential();
213
					var enc_c = CredentialService.encryptCredential(new_credential);
214
					SettingsService.setSetting('edit_credential', enc_c);
215
					$location.path('/vault/' + $scope.active_vault.guid + '/new');
216
				};
217
218
				$scope.editCredential = function (credential) {
219
					var _credential = angular.copy(credential);
220
					$rootScope.$emit('app_menu', false);
221
					SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
222
					$location.path('/vault/' + $scope.active_vault.guid + '/edit/' + _credential.guid);
223
				};
224
225
				$scope.getRevisions = function (credential) {
226
					var _credential = angular.copy(credential);
227
					$rootScope.$emit('app_menu', false);
228
					SettingsService.setSetting('revision_credential', CredentialService.encryptCredential(_credential));
229
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/revisions');
230
				};
231
232
				$scope.shareCredential = function (credential) {
233
					var _credential = angular.copy(credential);
234
					$rootScope.$emit('app_menu', false);
235
					SettingsService.setSetting('share_credential', CredentialService.encryptCredential(_credential));
236
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/share');
237
				};
238
239
				var notification;
240
				$scope.deleteCredential = function (credential) {
241
					var _credential = angular.copy(credential);
242
					try {
243
						_credential = CredentialService.decryptCredential(angular.copy(credential));
244
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
245
246
					}
247
					_credential.delete_time = new Date().getTime() / 1000;
248
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
249
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
250
							$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
251
						}
252
					}
253
					$scope.closeSelected();
254
					if (notification) {
255
						NotificationService.hideNotification(notification);
256
					}
257
					notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000,
258
						function () {
259
							CredentialService.updateCredential(_credential).then(function (result) {
260
								if (result.delete_time > 0) {
261
									notification = false;
262
263
								}
264
							});
265
						});
266
267
				};
268
269
				$scope.recoverCredential = function (credential) {
270
					var _credential = angular.copy(credential);
271
					try {
272
						_credential = CredentialService.decryptCredential(angular.copy(credential));
273
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
274
275
					}
276
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
277
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
278
							$scope.active_vault.credentials[i].delete_time = 0;
279
						}
280
					}
281
					_credential.delete_time = 0;
282
					$scope.closeSelected();
283
					if (notification) {
284
						NotificationService.hideNotification(notification);
285
					}
286
					NotificationService.showNotification($translate.instant('credential.recovered'), 5000,
287
						function () {
288
							CredentialService.updateCredential(_credential).then(function () {
289
								notification = false;
290
291
							});
292
						});
293
294
				};
295
296
				$scope.destroyCredential = function (credential) {
297
					var _credential = angular.copy(credential);
298
					CredentialService.destroyCredential(_credential.guid).then(function () {
299
						for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
300
							if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
301
								$scope.active_vault.credentials.splice(i, 1);
302
								NotificationService.showNotification($translate.instant('credential.destroyed'), 5000);
303
								break;
304
							}
305
						}
306
					});
307
				};
308
309
				$scope.view_mode = 'list'; //@TODO make this a setting
310
				$scope.switchViewMode = function (viewMode) {
311
					$scope.view_mode = viewMode;
312
				};
313
314
				$scope.filterOptions = {
315
					filterText: '',
316
					fields: ['label', 'username', 'email', 'custom_fields']
317
				};
318
319
320
				$scope.filtered_credentials = [];
321
				$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
322
					if (!$scope.active_vault) {
323
						return;
324
					}
325
					if ($scope.active_vault.credentials) {
326
						var credentials = angular.copy($scope.active_vault.credentials);
327
						var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
328
						filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
329
						filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
330
						$scope.filtered_credentials = filtered_credentials;
331
					}
332
				}, true);
333
334
				$scope.selectedtags = [];
335
				var to;
336
				$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
337
					var _selectedTags = [];
338
					for (var x = 0; x < _sTags.length; x++) {
339
						_selectedTags.push(_sTags[x].text);
340
					}
341
					$scope.selectedtags = _selectedTags;
342
					$timeout.cancel(to);
343
					if (_selectedTags.length > 0) {
344
						to = $timeout(function () {
345
							if ($scope.filtered_credentials) {
346
								var _filtered_tags = [];
347
								for (var i = 0; i < $scope.filtered_credentials.length; i++) {
348
									var tags = $scope.filtered_credentials[i].tags_raw;
349
									for (var x = 0; x < tags.length; x++) {
350
										var tag = tags[x].text;
351
										if (_filtered_tags.indexOf(tag) === -1) {
352
											_filtered_tags.push(tag);
353
										}
354
									}
355
								}
356
357
								$rootScope.$emit('limit_tags_in_list', _filtered_tags);
358
							}
359
						}, 50);
360
					}
361
				});
362
363
				$scope.delete_time = 0;
364
				$scope.showCredentialRow = function (credential) {
365
					if ($scope.delete_time === 0) {
366
						return credential.delete_time === 0;
367
					} else {
368
						return credential.delete_time > $scope.delete_time;
369
					}
370
371
				};
372
373
				$rootScope.$on('set_delete_time', function (event, time) {
374
					$scope.delete_time = time;
375
				});
376
377
				$scope.setDeleteTime = function (delete_time) {
378
					$scope.delete_time = delete_time;
379
				};
380
381
				$scope.selectedCredential = false;
382
				$scope.selectCredential = function (credential) {
383
					if(credential.description) {
384
						credential.description_html = $sce.trustAsHtml(angular.copy(credential.description).replace("\n", '<br />'));
385
					}
386
					$scope.selectedCredential = angular.copy(credential);
387
					$rootScope.$emit('app_menu', true);
388
				};
389
390
				$scope.closeSelected = function () {
391
					$rootScope.$emit('app_menu', false);
392
					$scope.selectedCredential = false;
393
				};
394
395
				$rootScope.$on('logout', function () {
396
					$scope.active_vault = null;
397
					$scope.credentials = [];
398
//				$scope.$parent.selectedVault = false;
399
400
				});
401
402
403
				$scope.downloadFile = function (credential, file) {
404
					var callback = function (result) {
405
						var key = null;
406
						if (!result.hasOwnProperty('file_data')) {
407
							NotificationService.showNotification($translate.instant('error.loading.file.perm'), 5000);
408
							return;
409
410
						}
411
						if (!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')) {
412
							if (credential.shared_key) {
413
								key = EncryptService.decryptString(angular.copy(credential.shared_key));
414
							}
415
						}
416
						if (credential.hasOwnProperty('acl')) {
417
							key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
418
						}
419
420
						var file_data = EncryptService.decryptString(result.file_data, key);
421
						download(file_data, escapeHTML(file.filename), file.mimetype);
422
423
					};
424
425
					if (!credential.hasOwnProperty('acl')) {
426
						FileService.getFile(file).then(callback);
427
					} else {
428
						ShareService.downloadSharedFile(credential, file).then(callback);
429
					}
430
431
				};
432
433
			}]);
434
}());